<!--
 * @Date: 2024-11-26 14:44:36
 * @Author: LiSong
 * @LastEditors: LiSong
 * @LastEditTime: 2025-03-21 09:30:30
 * @Description: 渲染页
-->
<template>
  <div class="hp-render">
    <GridLayout
      :="layoutAttrs"
      v-model:layout="renderState.layouts"
    >
      <GridItem
        v-for="item in renderState.layouts"
        :key="item.i"
        :="{
          ...item,
          isDraggable: false,
          isResizable: false,
        }"
        :id="item.i"
      >
        <PanelNode :grid="item" :design="design"/>
      </GridItem>
    </GridLayout>
  </div>
</template>

<script setup>
import XEUtils from 'xe-utils';
import { defAxios } from '@/utils/http';
import { reactive, watch } from 'vue';
import { pluginManager } from '@hp/utils/pluginManager.js'

import { PanelNode } from '@hp/comps/node'
import { GridLayout, GridItem } from 'grid-layout-plus'

const emits = defineEmits([
  'loaded',
])

const props = defineProps({
  // 是否设计模式
  design: {type: Boolean, default: false},
  // 布局信息
  layouts: { type: Array, default: () => [] },
  // 编码
  homeCode: { type: String, default: '' },
  // 是否自动加载
  autoLoad: { type: Boolean, default: true },
})

// 默认数据
const defInfo = {
  // 表单编码
  code: '',
  // 表单名称
  name: '',
  // 0-未启用 1-已启用
  status: 0,
  // 表单备注
  remark: '',
  // 唯一ID
  formId: '',
  // 表单类型
  formType: '',
  // 排序
  orderNum: 1,
  // 图片路径
  imageUrl: '',
  // 表单的种类 1-表单 2-主页
  category: '2',
  // 提交请求地址
  submitURL: '',
  // 表单类型名称
  formTypeName: '',
  // 校验规则
  validateContent: ''
}

const renderState = reactive({
  layouts: props.layouts,
  loading: false,
  baseInfo: {},
  dataLoaded: false,
})

const layoutAttrs = reactive({
  colNum: 120,
  rowHeight: 1,
  isDraggable: false,
  isResizable: false,
  verticalCompact: true,
  useCssTransforms: true,
})
const loadLayoutData = async () => {
  renderState.loading = true
  renderState.dataLoaded = false
  if (props.layouts && props.layouts.length > 0) {
    renderState.layouts = XEUtils.clone(props.layouts, true)
  } else {
    // 请求接口获取配置信息
    const data = await reqGetRenderInfo(props.homeCode)
    renderState.layouts = data.formJson
    renderState.baseInfo = data.baseInfo
  }
  // console.log('loadLayoutData', renderState)
  emits('loaded', XEUtils.clone(renderState, true))
  renderState.dataLoaded = true
  renderState.loading = false
}

/**
 * 合并基本信息
 * @param {Object} data 需要合并的数据
 * @param {Object} info 需要合并的数据
 */
const mergeBaseData = (data, row={}) => {
  let result = {}
  Object.keys(defInfo).forEach(key => {
    result[key] = data[key] || row[key] || defInfo[key]
  })
  return result
}

/**
 * 根据表单编码请求获取表单配置信息
 * 
 * @param formCode 表单编码
 */
const reqGetRenderInfo = (formCode) => {
  const result = {
    baseInfo: {},
    slotJson: [],
    formJson: []
  }
  return new Promise(resolve => {
    defAxios({
      url: '/prdFormInfo/queryPrdFormInfoListByFormCode',
      method: 'GET',
      params: { formCode }
    }).then(res => {
        if (res.code === 200) {
        const { data } = res
        const { prdFormContent } = data
        if (prdFormContent && prdFormContent.structureJson) {
          try {
            result.formJson = JSON.parse(prdFormContent.structureJson)
            // result.slotJson = JSON.parse(prdFormContent.slotJson)
            result.baseInfo = mergeBaseData({ ...data, ...prdFormContent })
          } catch (error) {
            console.error('解析表单数据失败', error)
          }
        }
        resolve(result)
      } else {
        resolve(result);
        console.error(res.msg)
      }
    }).catch(error => {
      resolve(result);
      console.error('获取配置数据失败', error)
    })
  })
}

watch(
  [
    () => props.layouts,
    () => props.homeCode,
  ],
  () => {
    loadLayoutData()
  },
  { deep: true, immediate: true, once: false }
)
// watch(
//   () => props.layouts,
//   () => {
//     loadLayoutData()
//   },
//   { deep: true, immediate: true }
// )


</script>

<style lang="scss" scoped>
.hp-render {
  position: relative;
  height: 100%;
  width: 100%;
  overflow: auto;
  overflow-x: hidden;
  // background-color: #fafafc;
}
:deep(.vgl-item:not(.vgl-item--placeholder)) {
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03), 
              0 1px 6px -1px rgba(0, 0, 0, 0.02),
              0 2px 4px 0 rgba(0, 0, 0, 0.02);
  border: 1px solid #ececec;
  border-radius: 4px;
  background-color: #ffffff;
  &:hover {
    box-shadow: 0 2px 12px #0000001a;
    transition: all ease .3s;
  }
  // &.checked {
  //   border: 1px solid #409eff;
  // }
}
:deep(.vgl-item__resizer) {
  &::before {
    border-color: #909399;
  }
}

:deep(.vgl-item--resizing) {
  opacity: 90%;
}

:deep(.vgl-item--static) {
  background-color: #cce;
}


.columns {
  columns: 120px;
}
</style>